import numpy as np
import pandas as pd
import matplotlib.pyplot as plt


def X_Y_ (pathname, colum):
    df = pd.read_csv(pathname, sep=',')
    df.apply(pd.to_numeric, axis=0)

    df.columns = [i for i in colum]
    # df = df.convert_objects(convert_numeric=True)
    # df.info()
    x = df[[df.columns[0]]].values
    y = df[[df.columns[1]]].values

    x = np.reshape(x, (x.shape[0],))
    y = np.reshape(y, (y.shape[0],))
    return x, y


class MyPredict():
    def __init__(self):
        pass

    # 计算损失函数
    def compute_cost(self, x, y, theta):
        y_pred = np.dot(x, theta.T)
        inner = np.power((y_pred - y), 2)
        cost = np.sum(inner, axis=0) / (2 * x.shape[0])
        return cost

    # 梯度下降
    def grandient_descent(self, x, y, theta, alpha, iters):
        # 参数长度
        len_params = theta.shape[1]
        # 迭代次数
        cost = np.zeros(shape=(iters, 2))
        cost[:, 0] = np.linspace(0, iters - 1, iters)
        for it in range(iters):
            error_val = np.dot(x, theta.T) - y
            error_val = np.reshape(error_val, (x.shape[0],))
            update_val_temp = np.zeros(shape=x.shape)
            for p in range(len_params):
                update_val_temp[:, p] = error_val * x[:, p]
            update_val = 2 * np.mean(update_val_temp, axis=0)

            # print(update_val[0])
            delta = alpha * update_val
            after = theta[0, 1]
            # print("after",after)
            theta = theta - delta
            # print("before",theta[0,1])
            # if (theta[0, 1]-after) < 0:   #
            #     break
            print('第%d次训练===截距：%f||斜率：%f' % (it, theta[0, 0], theta[0, 1]))
            cost[it, 1] = self.compute_cost(x, y, theta)
            print(cost[it, 1])
        return cost, theta

    # 画图函数
    def plot_(self, label, figsize_x, figsize_y, data, x_label, y_label, Title, color):
        if label is "cost":
            plt.figure(figsize=(figsize_x, figsize_y))
            plt.plot(data[:, 0], data[:, 1], color=color)
            plt.xlabel(x_label)
            plt.ylabel(y_label)
            plt.title(Title)
            plt.show()


if __name__ == "__main__":

    x, y = X_Y_('myhouse-1.csv', ['size', 'rental'])

    plt.figure(figsize=(10, 10))
    plt.scatter(x, y)

    # x插入一列值为1
    x = np.reshape(x, (-1, 1))
    x = np.insert(x, 0, 1, axis=1)
    y = np.reshape(y, (-1, 1))

    theta = np.zeros(shape=(1, x.shape[1]))
    alpha = 0.00001 # 学习率
    iters = 100  # 实验轮数
    mypredict = MyPredict()
    cost, theta_v = mypredict.grandient_descent(x, y, theta, alpha, iters)
    print("*" * 50)
    print(theta_v)

    b, k = theta_v[0, :]
    x_ = np.linspace(0, 350)
    y_ = x_ * k + b
    # 画A-R图
    plt.plot(x_, y_, color="r")
    plt.xlabel('Area[m²]')
    plt.ylabel('Rental[yuan/m]')
    plt.title('A-R Linear Regression')
    plt.show()
    # 画cost图
    mypredict.plot_("cost", 10, 10, cost, x_label="train count", y_label="cost", Title="A-R cost", color="b")
